import { C_ScrewColorEnum } from "../../C_Config";
import C_SwitchFrame from "../../component/C_SwitchFrame";
import C_App from "../../core/C_App";
import { C_NotificationConst } from "../../core/C_NotificationConst";
import C_SoundManager, { SoundName } from "../../core/utils/C_SoundManager";
import C_Hole from "./C_Hole";

const { ccclass, property } = cc._decorator;
/** 螺丝箱子 */
@ccclass
export default class C_Box extends cc.Component {

    _color: C_ScrewColorEnum;

    set color(v) {
        this._color = v;
    }

    get color() {
        return this._color;
    }

    @property()
    _targetColor: number = -1;

    @property()
    set targetColor(v) {
        this._targetColor = v;
    }

    get targetColor() {
        return this._targetColor
    }

    @property([C_Hole])
    holes: C_Hole[] = [];

    @property(C_SwitchFrame)
    bg1: C_SwitchFrame = null;

    @property(C_SwitchFrame)
    bg2: C_SwitchFrame = null;

    pos: number[] = [];
    total: number = 0;

    isActive: boolean = false;
    isInit: boolean = false;
    checkColor(color: C_ScrewColorEnum) {
        if (color == this.color) {
            return true;
        }
    }

    protected onLoad(): void {
        this.total = this.holes.length;
    }

    isAni: boolean = false;
    initBox(color: number, isAni: boolean = false) {
        this.holes.forEach(v => {
            v.initHole(color);
        })
        this.color = color;
        if (this.bg1) {
            this.bg1.frameIndex = this.bg2.frameIndex = color;
        }
        this.showBox();
        this._occupy = [];
        this.pos = [];
        if (isAni) {
            this.isActive = false;

            this.node.y = 500;
            this.isAni = true;
            cc.tween(this.node)
                .to(.1, { y: 0 })
                .delay(.1)
                .call(() => {
                    this.isActive = true;
                    this.isAni = false;
                })
                .start();
        }
        else {
            this.isActive = true;

            this.node.y = 0;
        }
    }

    showBox() {
        this.node.active = true;
    }

    hideBox() {
        this.node.active = false;
    }

    /** 获取空位 */
    getEmptyPos() {
        if (!this.isActive)
            return -1;
        let cnt = 0;
        while (cnt < this.total) {
            if (!this.pos[cnt] && !this._occupy[cnt]) {
                return cnt;
            }
            cnt++;
        }
        return -1;
    }

    hasEmptyPos() {
        if (this.isActive)
            return this.getEmptyPos() > -1;
    }

    getHolePosByIndex(index: number) {
        return this.holes[index].node.position
    }

    addScrew(pos: number, color?: C_ScrewColorEnum) {
        // const pos = this.getEmptyPos();
        // if (pos > -1) {
        this.removeOccupy(pos);
        this.holes[pos].addScrew(color !== undefined ? color : this.targetColor);
        if (this.targetColor !== -1) {
            const result = this.checkIsFull(true);
            if (result) {
                const x = this.node.x;
                this.isAni = true;
                cc.tween(this.node)
                    .to(.05, { x: x + 4 })
                    .to(.1, { x: x - 8 })
                    .to(.05, { x: x + 4 })
                    .union()
                    .repeat(3)
                    .call(() => {
                        C_SoundManager.instance.playEffect(SoundName.Success_Screw)
                    })
                    .to(.3, { y: 500 })
                    .delay(.1)
                    .call(() => {
                        this.isAni = false;
                        this.isActive = false;

                        this.node.x = x;
                        C_App.NotificationCenter.dispatch(C_NotificationConst.FULL_BOX, this);
                    })
                    .start();

            }
        }
        //     return true;
        // }
        // else {
        //     return false;
        // }
    }

    checkIsFull(isReal?: boolean) {
        if (isReal)
            for (const value of this._occupy) {
                if (value) {
                    return false;
                }
            }
        const isFull = !this.hasEmptyPos();
        if (isFull) {

            return true;
        }
        else {
            return false;
        }
    }

    _occupy: number[] = [];
    occupyPos(pos: number) {
        this._occupy[pos] = 1;
    }

    removeOccupy(pos: number) {
        this._occupy[pos] = 0;
        this.pos[pos] = 1;
    }

    removeScrew(pos: number) {
        if (this.pos[pos]) {
            this.holes[pos].removeScrew();
            this.pos[pos] = 0;
            return true;
        }
        else {
            return false;
        }
    }
}
